package com.hxd.mall.utils.open

import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.database.Cursor
import android.net.Uri
import android.os.Build
import android.provider.CallLog
import android.provider.ContactsContract
import android.telephony.TelephonyManager
import android.util.Log
import androidx.annotation.RequiresApi
import com.hexin.locallibrary.permssion.PermissionUtils
import com.hxd.mall.constant.HxdGlobalInfo
import com.hxd.mall.utils.open.PermissionUtil.tipPermissionText
import com.hxd.mall.utils.open.TimeUtil.getTimeFormat1ByDate
import com.hxd.threelibrary.getLocation
import java.util.*


/**
 *  Created by yinzhengwei on 2018/7/13.
 *  TODO 获取手机设备信息
 */
object MobileInfoManager {

    /**
     * 获取当前手机系统语言。
     *
     * @return 返回当前系统语言。例如：当前设置的是“中文-中国”，则返回“zh-CN”
     */
    fun getSystemLanguage() = Locale.getDefault().language!!

    /**
     * 获取当前系统上的语言列表(Locale列表)
     *
     * @return  语言列表
     */
    fun getSystemLanguageList(): Array<out Locale> = Locale.getAvailableLocales()!!

    /**
     * 获取当前手机系统版本号
     *
     * @return  系统版本号
     */
    fun getSystemVersion() = android.os.Build.VERSION.RELEASE!!

    /**
     * 获取手机型号
     *
     * @return  手机型号
     */
    fun getSystemModel() = android.os.Build.MODEL!!

    /**
     * 获取手机厂商
     *
     * @return  手机厂商
     */
    fun getDeviceBrand() = android.os.Build.BRAND!!

    /**
     * 获取手机IMEI(需要“android.permission.READ_PHONE_STATE”权限)
     *
     * @return  手机IMEI
     */
    @SuppressLint("MissingPermission", "HardwareIds")
    fun getIMEI(ctx: Context): String {
        return (ctx.getSystemService(Activity.TELEPHONY_SERVICE) as TelephonyManager).deviceId
    }

    /**
     * 判断是否打开了特定权限
     */
    //fun isOpenPermisson(context: Context, permisson: String) =
    //      ActivityCompat.checkSelfPermission(context, permisson) == PackageManager.PERMISSION_GRANTED

    /**
     * 打开特定权限
     */
//    fun openPermisson(context: Context, permisson: String) =
//            ActivityCompat.requestPermissions(context as Activity, arrayOf(permisson), 100)

    /**
     * 获取手机通讯录
     *
     * @return  通讯录列表
     */
    data class ContactsInfo(var vname: String, var number: String, var sortKey: String, var id: Int)

    fun getContactsList(context: Context): MutableList<ContactsInfo> {
        //if (!isOpenPermisson(context, Manifest.permission.READ_CONTACTS)) {
        //    openPermisson(context, Manifest.permission.READ_CONTACTS)
        //}
        val list = mutableListOf<ContactsInfo>()
        try {
            val contactUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
            val cursor = context.contentResolver.query(
                    contactUri,
                    arrayOf("display_name", "sort_key", "contact_id", "data1"),
                    null, null, "sort_key"
            ) ?: return list
            Log.d("cursor", "${cursor.count}")
            while (cursor.moveToNext()) {
                ContactsInfo(
                        cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)),
                        cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)),
                        if (cursor.getString(1).substring(0, 1).toUpperCase().matches("[A-Z]".toRegex())) {
                            cursor.getString(1).substring(0, 1).toUpperCase()
                        } else "#",
                        cursor.getInt(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.CONTACT_ID))
                ).run {
                    list.add(this)
                }
            }
            cursor.close()//使用完后一定要将cursor关闭，不然会造成内存泄露等问题
        } catch (e: Exception) {
            e.printStackTrace()
            return mutableListOf()
        }

        return list
    }


    /**
     * 获取手机通话记录
     *
     * @param isDesc是否降序排列（从最新的开始）
     *
     * CallLog.Calls.CACHED_FORMATTED_NUMBER      通话记录格式化号码
     * CallLog.Calls.CACHED_MATCHED_NUMBER     通话记录为格式化号码
     * CallLog.Calls.CACHED_NAME     联系人名称
     * CallLog.Calls.TYPE    通话类型
     * CallLog.Calls.DATE    通话时间(long型)
     * CallLog.Calls.DURATION     通话时长(秒为单位)
     * CallLog.Calls.GEOCODED_LOCATION    运营商地址(如：浙江杭州)
     * ----通话类型-----
     * CallLog.Calls.INCOMING_TYPE      呼入
     * CallLog.Calls.OUTGOING_TYPE      呼出
     * CallLog.Calls.MISSED_TYPE       未接
     *
     * @return  通话记录列表
     */
    data class CallRecord(
            var formatted_number: String = "", var matched_number: String = "",
            var name: String = "", var type: String = "", var date: String = "",
            var duration: String = "", var durationInt: Long, var callDate: Long,
            var typeOrigin: Int
    )

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN)
    @SuppressLint("MissingPermission")
    fun getCallLogList(context: Context, isDesc: Boolean): MutableList<CallRecord> {
        val resolver = context.contentResolver
        // uri的写法需要查看源码JB\packages\providers\ContactsProvider\AndroidManifest.xml中内容提供者的授权
        val projection = arrayOf(
                CallLog.Calls.CACHED_FORMATTED_NUMBER,
                CallLog.Calls.CACHED_MATCHED_NUMBER,
                CallLog.Calls.CACHED_NAME,
                CallLog.Calls.TYPE,
                CallLog.Calls.DATE,
                CallLog.Calls.DURATION)

        val list = mutableListOf<CallRecord>()

        try {
            // 从清单文件可知该提供者是CallLogProvider，且通话记录相关操作被封装到了Calls类中
            val cursor = resolver.query(
                    CallLog.Calls.CONTENT_URI, projection, null,
                    null, if (isDesc) "date DESC" else ""
            ) ?: return list

            val yearTime = 365 * 24 * 60 * 60 * 1000
//            val yearTime = 2 * 24 * 60 * 60 * 1000

            while (cursor.moveToNext()) {
                val formattedNumber = cursor.getColumnName(0) ?: ""
                val matchedNumber = cursor.getString(1) ?: ""
                val name = cursor.getString(2) ?: ""
                val type = cursor.getInt(3)
                val date = cursor.getLong(4)
                //将早于一年前的记录过滤掉
                if ((System.currentTimeMillis() - date) > yearTime)
                    continue
                val duration = cursor.getLong(5)
                val record = CallRecord(
                        formattedNumber, matchedNumber, name,
                        when (type) {
                            CallLog.Calls.INCOMING_TYPE -> "来电"
                            CallLog.Calls.OUTGOING_TYPE -> "去电"
                            CallLog.Calls.MISSED_TYPE -> "未接"
                            else -> {
                                ""
                            }
                        }, TimeFormatUtils.timeFormatSmsTimeLine(date, true),
                        TimeFormatUtils.formatDuration(duration),
                        duration,
                        date,
                        type
                )

                list.add(record)
            }

            cursor.close()
        } catch (e: Exception) {
            e.printStackTrace()
        }

        return list
    }

    /**
     * 获取手机所有短信
     *
     * _id：短信序号，如100
     *　thread_id：对话的序号，如100，与同一个手机号互发的短信，其序号是相同的
     *　address：发件人地址，即手机号，如+8613811810000
     *　person：发件人，如果发件人在通讯录中则为具体姓名，陌生人为null
     *　date：日期，long型，如1256539465022，可以对日期显示格式进行设置
     *　protocol：协议0SMS_RPOTO短信，1MMS_PROTO彩信
     *　read：是否阅读0未读，1已读
     *　status：短信状态-1接收，0complete,64pending,128failed
     *　type：短信类型1是接收到的，2是已发出
     *　body：短信具体内容
     * service_center：短信服务中心号码编号，如+8613800755500
     */
    data class SmsInfo(
            var _id: Int, var thread_id: Int, var address: String,
            var person: String, var date: String, var protocol: String, var read: String,
            var status: String, var type: String, var body: String, var service_center: String
    )

    @SuppressLint("Recycle")
    fun getSmsFromPhone(context: Context, isDesc: Boolean): MutableList<SmsInfo> {
        val SMS_INBOX = Uri.parse("content://sms/")
        val cr = context.contentResolver
        val projection = arrayOf(
                "_id", "thread_id", "address", "person", "date",
                "protocol", "read", "status", "type", "body", "service_center"
        )
        val cur = cr.query(
                SMS_INBOX, projection, null, null,
                if (isDesc) "date DESC" else ""
        )
        if (null == cur) {
            Log.i("ooc", "************cur == null")
            return mutableListOf()
        }

        val yearTime = 365 * 24 * 60 * 60 * 1000
//        val yearTime = 2 * 24 * 60 * 60 * 1000
        val list = mutableListOf<SmsInfo>()
        while (cur.moveToNext()) {
            val service_center = cur.getString(cur.getColumnIndex("service_center"))
            val body = cur.getString(cur.getColumnIndex("body"))
            val type = cur.getString(cur.getColumnIndex("type"))
            val status = cur.getString(cur.getColumnIndex("status"))
            val read = cur.getString(cur.getColumnIndex("read"))
            val protocol = cur.getString(cur.getColumnIndex("protocol"))

            val date = cur.getLong(cur.getColumnIndex("date"))
            //将早于一年前的记录过滤掉
            if ((System.currentTimeMillis() - date) > yearTime)
                continue

            val person = cur.getString(cur.getColumnIndex("person"))
            val address = cur.getString(cur.getColumnIndex("address"))
            list.add(
                    SmsInfo(
                            cur.getInt(cur.getColumnIndex("_id")),
                            cur.getInt(cur.getColumnIndex("thread_id")),
                            address ?: "",
                            person ?: "",
                            getTimeFormat1ByDate(date),
                            protocol ?: "",
                            read ?: "",
                            status ?: "",
                            type ?: "",
                            body ?: "",
                            service_center ?: ""
                    )
            )
        }
        return list
    }

    //这里新增权限的提示是因为在 OppoR9s 6.0.1手机上权限判断无效的原因
    @SuppressLint("MissingPermission")
    fun isMissingPermission(context: Activity, callback: (Boolean) -> Unit) {
        try {
            //联系人
            val contactUri = ContactsContract.CommonDataKinds.Phone.CONTENT_URI
            val resolver = context.contentResolver
            var cursor = resolver.query(contactUri, arrayOf("display_name", "sort_key", "contact_id", "data1"), null, null, "sort_key")
            if (isEmpty(context, cursor, callback))
                return

            //通话记录
            var projection = arrayOf(
                    CallLog.Calls.CACHED_FORMATTED_NUMBER,
                    CallLog.Calls.CACHED_MATCHED_NUMBER,
                    CallLog.Calls.CACHED_NAME,
                    CallLog.Calls.TYPE,
                    CallLog.Calls.DATE,
                    CallLog.Calls.DURATION)
            cursor = resolver.query(CallLog.Calls.CONTENT_URI, projection, null, null, "")
            if (isEmpty(context, cursor, callback))
                return

            //短信
            projection = arrayOf(
                    "_id", "thread_id", "address", "person", "date",
                    "protocol", "read", "status", "type", "body", "service_center")
            cursor = resolver.query(Uri.parse("content://sms/"), projection, null, null, "")
            if (isEmpty(context, cursor, callback))
                return

            getLocation(HxdGlobalInfo.instance) {
                if (it.latitude == 0.0) {
                    callback(false)
                    PermissionUtils.showPermissions(context, tipPermissionText(), 10009) {}
                } else {
                    callback(true)
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
            isEmpty(context, null, callback)
        }
    }

    private fun isEmpty(context: Activity, cursor: Cursor?, callback: (Boolean) -> Unit): Boolean {
        return if (cursor == null) {
            PermissionUtils.showPermissions(context, tipPermissionText(), 10009) {}
            callback(false)
            true
        } else {
            cursor.close()
            false
        }
    }

}